#pragma once

namespace	MomogenkyouSystem	{

class	ScreenManager;

enum	ScreenState
{
	TransitionOn	=	0,
    Active			=	1,
    TransitionOff	=	2,
    Hidden			=	3,
};

// A screen is a single layer that has update and draw logic, and which
// can be combined with other layers to build up a complex menu system.
// For instance the main menu, the options menu, the "are you sure you
// want to quit" message box, and the main game itself are all implemented
// as screens.

class	ScreenTemplate
{
	friend	class	ScreenManager;

	bool						UpdateTransition(const float & fInterval, const float & fElapsedTime, const int & nDirection);
protected:
	std::string					m_ScreenName;
	//SmartPtr<ScreenManager>		m_pScreenManager;		//	manager that this screen belongs to.
	ScreenState					m_ScreenState;			//	Current State of Transition
	
	bool						m_bIsExiting;			//	Indication whether the screen really exist

	bool						m_bFocusedOtherScreen;	//	Indicate whether the screen is active and respond to user

	bool						m_bIsPopup;				//	indicates whether the screen is only a small
														//	popup, in which case screens underneath it do not need to bother
														//	transitioning off.
	
	float						m_fTransitionOnTime;	//	Indicates how long the screen takes to appear on when activated.
	float						m_fTransitionOffTime;	//	Indicates how long the screen takes to fade on when deactivated.

	float						m_fTransitionPosition;	//	Ratio of transisition 0 (full active) ~ 1.0 (empty)
public:
	bool						IsModal;				//	Modal screen will block user input from other screen

	ScreenTemplate();
	virtual	~ScreenTemplate();

	inline	std::string			ScreenName()			const		{	return	m_ScreenName;			}
	//inline	ScreenManager	*	ScreenManager()			const		{	return	m_pScreenManager.get();	}
	inline	ScreenState			ScreenState()			const		{	return	m_ScreenState;			}
	inline	bool				IsExiting()				const		{	return	m_bIsExiting;			}
	inline	bool				IsPopup()				const		{	return	m_bIsPopup;				}
	inline	float				TransitionOnTime()		const		{	return	m_fTransitionOnTime;	}
	inline	float				TransitionOffTime()		const		{	return	m_fTransitionOffTime;	}
	inline	float				TransitionPosition()	const		{	return	m_fTransitionPosition;	}
	//	Gets the current alpha of the screen transition, ranging
    //	from 255 (fully active, no transition) to 0 (faded to nothing).
	inline	BYTE				TransitionAlphaBYTE()	const		{	return	255 - static_cast<BYTE>(m_fTransitionPosition * 255);	}
	inline	float				TransitionAlphaFLOAT()	const		{	return	1.0f - m_fTransitionPosition;							}

	//	m_ScreenState < 2	=	TransitionOn || Active
	inline	bool				IsActive()				const		{	return	!m_bFocusedOtherScreen && m_ScreenState < 2;			}

	
	virtual	void				Initialize();
	virtual	void				Shutdown();
	virtual	void				Update(const float & fInterval);
	virtual	void				ProcessInput();
	virtual	void				DrawGameScreen(const float & fInterval);
	
	//	Allows the screen to run logic, such as updating the transition position.
    //	Unlike HandleInput, this method is called regardless of whether the screen
    //	is active, hidden, or in the middle of a transition.
			void				UpdateScreen(const float & fInterval, const bool & bFocusOther, const bool & bCoveredByOther);
	
	//	Tells the screen to go away. Unlike ScreenManager.RemoveScreen, which
    //	instantly kills the screen, this method respects the transition timings
    //	and will give the screen a chance to gradually transition off.
			void				ExitScreen();
};

}